package main

import (
	"fmt"
	"time"
	"math"
)

const(
	name string ="zhangsan"
	age int8 = 100
	code int = 12222
)


func main() {

	var a int = 32

	fmt.Printf("name : %s age %d code %d a %d",name,age , code ,a)

	if a == 32 {
		fmt.Printf("%s","32为32")
	}

	for true{
		if a == 32 {
			fmt.Printf("\n%s","32为32,无线循环结束")
			break
		}
	}

	for b := 0; b < 5; b++ {
		fmt.Printf("\n %d \n",b)
	}


/**
 *    多参数赋值，返回多参数函数。
 */
	a,b := 2,5
	c,d :=swap(a,b)
	fmt.Println(a,b,c,d)


/**
 *	& :得到变量的地址。
 */
	swap2( &a ,&b)
	fmt.Println(a,b,c,d)



	for i :=0; i < 5; i++  {
		switchFunc(i)
	}

	for i :=0; i < 5; i++  {
		selectFunc()
	}

	timeoutChannel();



	/* 将函数赋值给一个引用  函数引用：getSquareRoot*/
	getSquareRoot := func(x float64) float64 {
		return math.Sqrt(x)
	}
	/* 使用函数 */
	fmt.Println(getSquareRoot(9))



	/**
	 *  得到函数的引用
	 */
	getSquareRo := getSequence()
	for i :=0 ; i < 5; i++  {
		fmt.Println(getSquareRo())
	}
}

/**
 *	返回多参数：fun 函数名 （参数 类型）（返回值类型）
 */
func swap(x int, y int) (int, int) {
	return y, x
}


/**
 *	返回多参数：fun 函数名 （参数 类型）（返回值类型）
 */
func swap1(x , y int) (int, int) {
	return y, x
}


/**
 *   指针函数。
 */
func swap2(x *int, y *int) {
	var temp int
	temp = *x    /* 保持 x 地址上的值 */
	*x = *y      /* 将 y 值赋给 x */
	*y = temp    /* 将 temp 值赋给 y */
}


/**
 * switch value 函数
 */
func switchFunc(i int)  {
	switch i {
	case 1:fmt.Println(1)
	case 2:fmt.Println(2)
	case 3,4,5:fmt.Println(3,4,5)
	case 6:fmt.Println(6)
	default:
		fmt.Println("别的参数")
	}
}


/**
 * select 检测chan是否流入信息
 *
 * <-ch1：   能否移除元素，成功执行case语句。 空不能移除。
 * ch1 <- 3：能否添加元素，成功执行case语句。 满则不能添加。
 *
 * 因为 ch1 和 ch2 都为空，所以 case1 和 case2 都不会读取成功。 则 select 执行 default 语句。
 * 就是因为这个 default 特性， 我们可以使用 select 语句来检测 chan 是否已经满了。
 */
func selectFunc()  {
	ch1 := make (chan int, 2)
	ch2 := make (chan int, 2)
	select {
	case <-ch1:
		fmt.Println("ch1 pop one element")
	case <-ch2:
		fmt.Println("ch2 pop one element")
	case ch1 <- 3:
		fmt.Println("ch1 put one element")
	case ch1 <- 4:
		fmt.Println("ch1 put one element")
	default:
		fmt.Println("default")
	}
}
/**
 * 等待通道内容，并调价超时机制。
 */
func timeoutChannel()  {
	timeout := make (chan bool, 1)
	/**
	 * 闭包
	 */
	go func() {
		time.Sleep(1e9) // sleep one second
		timeout <- true
	}()

	//等待若干时间后，先检测ch是否有数值，有的话，执行case后面的。 ch没有的话，直接timeout。
	ch := make (chan int)
	select {
	case <- ch:
	case <- timeout:
		fmt.Println("timeout!")
	}
}

/*
 *  函数的返回值为函数： func() int
 */
func getSequence() func() int {
	i:=0
	return func() int {
		i+=1
		return i
	}
}